<template>
	<view class="" hover-class="none" hover-stop-propagation="false">
		<canvas type="2d" id="myCanvas" ref="cav" class="resize"></canvas>
	</view>

</template>
<script>
let cfgPathStr = 'modelCfg.json';
let Module = null;
let modeNum = null;
let cfg;
let business;
let mo;
let output;
let dst;

export default {
	data() {
		return {
			result: -1,
			// 切换业务类型 businessType = "SignOut" OR "SignIn" 
			// 主要切换 businessTypeStr 即可 
			businessTypeStr: 'SignIn',
			modeStr: 'detect',

		};
	},
	created() {

	},

	methods: {
		awaitTimes(timeout) {
			return new Promise((resolve) => {
				setTimeout(() => {
					resolve();
				}, timeout);
			});
		},

		async sendToSIDAAI(imageData, success, options) {
			if (!Module) {
				return;
			}

			let start = new Date().getTime();
			// 给图片输入分配内存
			dst = Module._malloc(imageData.data.length); 
			Module.HEAPU8.set(imageData.data, dst);
			console.log('dst', dst);

			// 给输出分配内存
			const maxLength = 256 * 300;
			output = Module._malloc(maxLength);

			let outputDeterNum = Module._malloc(maxLength);
 
			// 分配内存和指针
			cfg = this.allocateString(cfgPathStr);
			business = this.allocateString(this.businessTypeStr);
			mo = this.allocateString(this.modeStr);

			// 模型初始化与模型加载；这里主要是针对检测接口进行加载
			Module._SIDAAIInit(cfg, business, mo);
			await this.awaitTimes(200);
			console.log('1--------Detect:SIDA Init Finished.');

			Module._SIDAAILoadModel(business, mo);
			console.log('2--------Detect:SIDA Load Models Finished.', imageData.width, imageData.height);
			await this.awaitTimes(200);

			Module._SIDAAI(dst, imageData.width, imageData.height, business, mo, output);
			console.log('3--------Detect:SIDA Inference Finished.');
			Module._SIDAAIRelease(business, mo);
			
			// 这里需要判断是否是签到业务；
			// 由于签到业务是检测（detect）和判断（determine）接口分开；
			// 所以检测完需要将接口换成判断接口；
			//  
			// 确保推理之前完成初始化
			mo = this.free(mo);
			output = this.free(output);
			await this.awaitTimes(200);
			let determine = 'determine';
			mo = this.allocateString(determine);

			Module._SIDAAILoadModel(business, mo);
			console.log('4----------Determine:SIDA Load Models Finished.');
			await this.awaitTimes(200);
			Module._SIDAAI(dst, imageData.width, imageData.height, business, mo, outputDeterNum);
			await this.awaitTimes(200);
			console.log('5-----------Determine:SIDA Inference Finished.');
			Module._SIDAAIRelease(business, mo);
			const modelResult = Module.UTF8ToString(outputDeterNum);
			let end = new Date().getTime();
			let times = ((end - start) / 1000).toFixed(1);
			console.log('用时：' + times + 's');
			this.result = -1;
			let resultOpt = (JSON.parse(modelResult || '{}'));
			this.getResult(resultOpt); 
			// console.log(111111111, this.result );
			success({ ...resultOpt, ...options,result:this.result });

			// 释放指针和内存
			console.log('6--------- -allFree');
			outputDeterNum = this.free(outputDeterNum);
			this.allFree();
		},

		getResult(res) {
			if (!res) {
				return;
			}
			for (const key in res) {
				if (res[key] && typeof res[key] == 'object') {
					for (const key2 in res[key]) {
						 if (key2 == 'determine') {
							this.result = this.result < res[key].determine ? res[key].determine : this.result;
							break;
						 }
						 if (typeof res[key][key2] == 'object' && typeof key2 != 'number') {
							this.getResult(res[key]);
						 }
					}
				}
			}
			return this.result;
		},

		allocateString(str) {
			const intArray = Module.intArrayFromString(str);
			const ptr = Module._malloc(intArray.length + 1);
			Module.HEAP8.set(intArray, ptr);
			console.log(`Allocated memory for string: ${str}, ptr: ${ptr}, length: ${intArray.length}`);
			return ptr;
		},
		checkFree(state) {
			console.log(state + ' cfg', cfg);
			console.log(state + ' business', business);
			console.log(state + ' mo', mo);
			console.log(state + ' output', output);
		},
		allFree() {
			cfg = this.free(cfg);
			business = this.free(business);
			mo = this.free(mo);
			output = this.free(output);
			dst = this.free(dst);
		},
		free(ptr) {
			if (ptr != null) {
				console.log(`Freeing memory for pointer: ${ptr}`);
				Module._free(ptr);
				ptr = null;
			}
			return ptr;
		},
		// 将图片绘制到 2D 画布
		async drawImageToCanvas({ businessTypeStr, imagePath, success }) {
			if (businessTypeStr) {
				this.businessTypeStr = businessTypeStr;
			}

			this.awaitTimes(200);
			return new Promise((resolve) => {
				wx.getImageInfo({
					src: imagePath,
					success: infoRes => {
						if (!Module) {
							Module = getApp().globalData.Module;
						}

						// Module = deepCopy(getApp().globalData.Module);

						const canvas = this.$refs.cav;
						console.log('infoRes', infoRes, canvas);
						let imgWidth = infoRes.width;
						let imgHeight = infoRes.height;

						// if (infoRes.width > 100) {
						// 	let rig = (imgHeight / imgWidth).toFixed(2);
						// 	imgWidth = 100;
						// 	imgHeight = 100 * rig;
						// }
						console.log('imgWidth', imgWidth, imgHeight);
						this.$nextTick(() => {
							this.createSelectorQuery()
								.select('#myCanvas') // 使用 canvas 的 id
								.fields({ node: true, size: true })
								.exec((res) => {
									console.log('canvas元素信息:', res);
									const canvas = res[0].node;
									const ctx = canvas.getContext('2d');

									canvas.width = imgWidth;
									canvas.height = imgHeight;

									const img = canvas.createImage();
									img.src = imagePath;
									img.onload = () => {
										ctx.clearRect(0, 0, canvas.width, canvas.height);
										ctx.drawImage(img, 0, 0, imgWidth, imgHeight);
									};

									// 确保在图片绘制完成之后再调用 getImageData
									setTimeout(() => {
										const imageData = ctx.getImageData(0, 0, imgWidth, imgHeight);
										console.log('imageData', imageData);
										this.sendToSIDAAI(imageData, success, { width: imgWidth, height: imgHeight });
									}, 100);
								});
						});
					},
					fail: err => {
						console.error('Failed to get image info:', err);
					}
				});
			});
		},

	}
};

</script>
<style scoped>
.resize {
	width: 150px;
	height: 250px;
	position: fixed;
	left: -400px;
	bottom: -100px;

}
</style>